import url from 'url';
import path from 'path';
import fs from 'fs';
import mime from 'mime-types';
import zlib from 'zlib';

const config={
	fileMatch: /^(woff|ttf|svg|eot|woff2|otf|html|htm|jpeg|pdf|txt|json|exe|doc|docx|zip|ppt|xml|shtml|bmp|mp3|ogg|wav|gif|png|jpg|js|css)$/ig,
    maxAge: 60 * 60 * 24 * 365
}

const cdnApp = (req,res) => {

	return (target)=>{
		let pathname=target;
		let locExist=fs.existsSync(target);
		if (locExist) {
			let isDir=fs.statSync(target).isDirectory();
			if (isDir) {
				pathname=target+(/\\|\/$/.test(target)?'':'/')+url.parse(req.url).pathname;
				pathname+=(/\.\w+$/i.test(pathname)?'':'/index.html');
			}
		}else{
			res.writeHead(404,{
				'content-type':'text/plain'
			});
			res.end('[Config.proxyTarget]:local path is not exist !');
		};
		let realpath=path.normalize(pathname.replace(/\.\./g,''));
		let extname=path.extname(realpath);
		extname=extname?extname.slice(1):'unknown';
		let type=mime.types[extname]||'text/plain';

		fs.exists(realpath,exist=>{
			if(!exist){
				console.log('GET 404 '+pathname);
				res.writeHead(404,{
					'content-type':'text/plain'
				});
				res.end('source not found !');
			}else{
				fs.readFile(realpath,'binary',(err,file)=>{
					if(err){
						res.writeHead(500,{
							'content-type':'text/plain'
						});
						console.log('GET 500 '+pathname);
						res.end('internal server error !');
						return false;
					}
					if(extname.match(config.fileMatch)){
						let expires=new Date();
						expires.setTime(expires.getTime()+config.maxAge*1000);
						res.setHeader('Expires',expires.toUTCString());
						res.setHeader('cache-control','max-age='+config.maxAge);
					}
					fs.stat(realpath,(err,stat)=>{
						let lastModified=stat.mtime.toUTCString();
						res.setHeader('Last-Modified',lastModified);
						
						if(req.headers['if-modified-since']&&lastModified==req.headers['if-modified-since']){
							res.writeHead(304,{
								'content-type':type,
								'Access-Control-Allow-Origin':'*'
							});
							console.log('GET 304 '+pathname);
							res.end();
						}else{
							let raw=fs.createReadStream(realpath);
							let acceptEncoding=req.headers['accept-encoding']||'';
							// let matched=extname.match(/css|js|html|xml|jpg|png|gif/ig);
							if(acceptEncoding.match(/\bgzip\b/)){
								res.writeHead(200,{
									'content-type':type,
									'Content-Encoding':'gzip',
									'Access-Control-Allow-Origin':'*'
								});
								raw.pipe(zlib.createGzip()).pipe(res);
							}else if(acceptEncoding.match(/\bdeflate\b/)){
								res.writeHead(200,{
									'content-type':type,
									'Content-Encoding':'deflate',
									'Access-Control-Allow-Origin':'*'
								});
								raw.pipe(zlib.createDeflate()).pipe(res);
							}else{
								res.writeHead(200,{
									'content-type':type,
									'Access-Control-Allow-Origin':'*'
								});
								raw.pipe(res);
							}
							console.log('GET 200 '+pathname);
						}
					});
				});
			}
		});
	}
	
}

export default cdnApp;